

#include <QtQml>


#include <Utility/UiLoader.h>
#include <Data/User.h>

#include <Request/FileUploader.h>
#include <Request/Login.h>
#include <Request/Register.h>
#include <Request/RegisterValidator.h>
#include <Request/UserInfo.h>
#include <Request/MultiPostFetcher.h>
#include <Request/MultiPostSubmitter.h>
#include <Request/TeacherGroupsFetcher.h>
#include <Request/NewsQuery.h>
#include <Request/NewsGroupQuery.h>
#include <Request/Downloader.h>

#include <TCServerCore/Type/Permission.h>

#include "Engine.h"
#include "TypeRegister.h"

namespace TC
{
    namespace Qml
    {
        template<class T>
        static QObject *qmlSingletonCallback(QQmlEngine *, QJSEngine *)
        {
            return T::instance();
        }

        void registerAllRequests()
        {
            using namespace Request;

            FileUploader::initGlobal();

            qmlRegisterType<FileUploader>("Cpp.Request", 1, 0, "FileUploader");
            qmlRegisterType<Login>("Cpp.Request", 1, 0, "Login");
            qmlRegisterType<Register>("Cpp.Request", 1, 0, "Register");
            qmlRegisterType<RegisterValidator>("Cpp.Request", 1, 0, "RegisterValidator");
            qmlRegisterType<UserInfo>("Cpp.Request", 1, 0, "UserInfo");
			qmlRegisterType<MultiPostFetcher>("Cpp.Request", 1, 0, "MultiPostFetcher");
            qmlRegisterType<MultiPostSubmitter>("Cpp.Request", 1, 0, "MultiPostSubmitter");
            qmlRegisterType<TeacherGroupsFetcher>("Cpp.Request", 1, 0, "TeacherGroupsFetcher");
			qmlRegisterType<NewsQuery>("Cpp.Request", 1, 0, "NewsQuery");
			qmlRegisterType<NewsGroupQuery>("Cpp.Request", 1, 0, "NewsGroupQuery");
			qmlRegisterType<Downloader>("Cpp.Request", 1, 0, "Downloader");
        }

        void registerAllTypes()
        {
            auto enumMessage = QStringLiteral("Enum Type is not creatable");
			//qmlRegisterUncreatableType<Permission_Enum>("Cpp.Type", 1, 0, "Permission", enumMessage);
			qmlRegisterUncreatableType<Subject_Enum>("Cpp.Type", 1, 0, "Subject", enumMessage);
		}

        void registerAllUtils()
        {
            using namespace Utility;
            qmlRegisterSingletonType<UiLoader>("Cpp.Utility", 1, 0, "UiLoader", &qmlSingletonCallback<UiLoader>);
            qmlRegisterSingletonType<Engine>("Cpp.Utility", 1, 0, "Engine", &qmlSingletonCallback<Engine>);
        }

        void registerAllDatas()
        {
            using namespace Data;
            qmlRegisterSingletonType<User>("Cpp.Data", 1, 0, "User", &qmlSingletonCallback<User>);
        }

        void registerAll()
        {
            registerAllRequests();
            registerAllTypes();
            registerAllUtils();
            registerAllDatas();
        }
    }
}
